

#include "collectionscene.h"
#include "armiesscene.h"
#include "resourcemanager.h"
#include "log.h"
#include "messagequeue.h"
#include "gamemanager.h"
#include "gamedatamanager.h"
#include "CCSkeletalSprite.h"
#include "cocos-ext.h"
#include "equipmentdetaillayer.h"

static const int COLS_PER_LINE = 4;
static const int VIEW_MARGIN = 18;
static const int ITEM_WIDTH = 80;
static const int ITEM_HEIGHT = 80;
static const int ITEM_SPACE = 5;
static const int DRAGGING_OFFSET_X = 50;
static const int DRAGGING_OFFSET_Y = 50;

static const int TAG_QUANTITY_PAD = 100;
static const int TAG_QUANTITY_LABEL = 200;

static float scales[] = {1.0f, 0.8f, 0.8f, 0.8f, 0.8f};

CollectionScene::CollectionScene():
_layer(nullptr)
, _layerEquipmentDetail(nullptr)
, _touchPlace(CollectionSceneTouchPlace::blank)
, _selectedTabIndex(0)
, _touchedTabButtonIndex(-1)
, _touchedEquipmentIndex(-1)
, _draggingStartPos(CCPointZero) {
	memset(_tabButtons, 0, sizeof(_tabButtons));
	memset(_layerEquipments, 0, sizeof(_layerEquipments));

	_arrSprites[0] = &_arrCreatureSprites;
	_arrSprites[1] = &_arrWeaponSprites;
	_arrSprites[2] = &_arrArmorSprites;
	_arrSprites[3] = &_arrShieldSprites;
	_arrSprites[4] = &_arrSpecialSprites;
}

CollectionScene::~CollectionScene() {
}

bool CollectionScene::init() {
	if (!CCScene::init()) {
		return false;
	}

	_layer = CCLayer::create();
	_layer->setTouchEnabled(false);
	addChild(_layer);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	CCSprite *spr = CCSprite::create("textures/ui_bg.png");
#else
	CCSprite *spr = CCSprite::create("textures/ui_bg.png");
#endif

	spr->setAnchorPoint(CCPointZero);

	CCSize size = spr->getContentSize();
	spr->setScaleX(GM->screenSize.width / size.width);
	spr->setScaleY(GM->screenSize.height / size.height);
	_layer->addChild(spr);

	createTabButtons();
	createEquipments();
	createSmeltingPad();

	cocos2d::extension::CCScale9Sprite *sprEquipmentBg = cocos2d::extension::CCScale9Sprite::create("textures/frame.png", CCRectMake(0, 0, 96, 96), CCRectMake(32, 32, 32, 32));
	sprEquipmentBg->setContentSize(CCSizeMake(X_SCALE(850), Y_SCALE(GameManager::BASE_HEIGHT)));
	sprEquipmentBg->setPosition(XY_SCALE(102, 0));
	sprEquipmentBg->setAnchorPoint(CCPointZero);
	_layer->addChild(sprEquipmentBg);

	auto btnExit = RM->makeBackButton(this, menu_selector(CollectionScene::onClose), _layer, true);
	btnExit->setPosition(XY_SCALE(845, 535));

	_layerEquipmentDetail = EquipmentDetailLayer::create();
	_layerEquipmentDetail->setVisible(false);
	addChild(_layerEquipmentDetail);

	return true;
}

void CollectionScene::createTabButtons() {
	int x = 10;
	int arr_y_pos[] = {476, 366, 255, 145, 40};
	char buf[50];

	for (int i = 0; i < 5; i++) {
		if (i == 0) {
			_tabButtons[i] = MAKE_SPRITE("button/round_button_1.png");
			_tabButtons[i]->setPosition(XY_SCALE(0, arr_y_pos[i]));
		} else {
			_tabButtons[i] = MAKE_SPRITE("button/round_button_0.png");
			_tabButtons[i]->setPosition(XY_SCALE(x, arr_y_pos[i]));
		}

		_tabButtons[i]->setAnchorPoint(CCPointZero);

		_layer->addChild(_tabButtons[i]);

		sprintf(buf, "equipment_icon_%s.png", EQUIPMENT_TYPE_NAMES[i]);
		CCSprite *spr = MAKE_SPRITE(buf);
		spr->setScale(1.0f);
		spr->setPosition(ccp(48, 48));
		_tabButtons[i]->addChild(spr);
	}
}

void CollectionScene::createEquipments() {
	CCSize bgSize = CCSizeMake(X_SCALE(410), Y_SCALE(555));

	cocos2d::extension::CCScale9Sprite *sprEquipmentBg = cocos2d::extension::CCScale9Sprite::create("textures/pad_bg.png", CCRectMake(0, 0, 225, 225), CCRectMake(100, 100, 25, 25));
	sprEquipmentBg->setContentSize(bgSize);
	sprEquipmentBg->setPosition(ccp(X_SCALE(115), GM->screenSize.height / 2));
	sprEquipmentBg->setAnchorPoint(ccp(0.0f, 0.5f));
	_layer->addChild(sprEquipmentBg);

	vector<string> *arrAttrs[] = {&(GDM->creatures), &(GDM->weapons), &(GDM->armors), &(GDM->shields), &(GDM->specials)};
	char buf[50];

	for (int i = 0; i < (int) EquipmentType::count; i++) {
		int rows = arrAttrs[i]->size() / COLS_PER_LINE;
		if (arrAttrs[i]->size() % COLS_PER_LINE > 0) {
			rows++;
		}

		_DHLOG("%s, size:%d, columns: %d, rows: %d", EQUIPMENT_TYPE_NAMES[i], arrAttrs[i]->size(), COLS_PER_LINE, rows);

		CCSize size(X_SCALE((ITEM_WIDTH + ITEM_SPACE) * COLS_PER_LINE - ITEM_SPACE), Y_SCALE((ITEM_HEIGHT + ITEM_SPACE) * rows - ITEM_SPACE));
		_arrItemRows[i] = rows;

		CCSize clippingSize = CCSizeMake(size.width, bgSize.height - Y_SCALE(VIEW_MARGIN) * 2);

		CCClippingNode *clippingNode = CCClippingNode::create();
		clippingNode->setAnchorPoint(ccp(0.5f, 0.5f));
		clippingNode->setPosition(ccp(sprEquipmentBg->getPositionX() + bgSize.width / 2, sprEquipmentBg->getPositionY()));
		clippingNode->setContentSize(clippingSize);

		CCPoint vertices[] = {
				ccp(0, 0),
				ccp(clippingSize.width, 0),
				ccp(clippingSize.width, clippingSize.height),
				ccp(0, clippingSize.height)
		};

		ccColor4F black = {1, 1, 1, 1};
		CCDrawNode *stencil = CCDrawNode::create();
		stencil->drawPolygon(vertices, 4, black, 1, black);
		clippingNode->setStencil(stencil);

		_layer->addChild(clippingNode);

		CCLayer *layer = CCLayer::create();
		layer->setAnchorPoint(CCPointZero);
		layer->setContentSize(size);
		layer->setPosition(ccp(0, clippingSize.height - size.height));
		layer->setVisible(false);

		clippingNode->addChild(layer);
		_layerEquipments[i] = layer;

		int index = 0;
		float x = X_SCALE(ITEM_WIDTH / 2);
		float y = Y_SCALE(ITEM_HEIGHT / 2);
		for (auto name : *(arrAttrs[i])) {
			const EquipmentAttribute& attr = GDM->equipmentsAttribute[name];

			auto pt = ccp(x, size.height - y);

			CCSprite *itemFrame = MAKE_SPRITE("equipment_pad.png");
			itemFrame->setPosition(pt);
			layer->addChild(itemFrame);

			if (attr.rarity != EquipmentRarity::common) {
				sprintf(buf, "rarity_color_%s.png", RARITY_NAMES[(int) attr.rarity]);
				CCSprite *itemRarityBg = MAKE_SPRITE(buf);
				itemRarityBg->setPosition(ccp(itemFrame->getContentSize().width / 2, itemFrame->getContentSize().height / 2));
				itemFrame->addChild(itemRarityBg);
			}

			string iconFile = GDM->getEquipmentIconFileName((EquipmentType) i, attr.name);
			CCSprite *spr = MAKE_SPRITE(iconFile);
			spr->setScale(scales[i]);
			spr->setPosition(ccp(itemFrame->getContentSize().width / 2, itemFrame->getContentSize().height / 2));
			itemFrame->addChild(spr);

			CCSprite *sprQuantityPad = MAKE_SPRITE("quantity_pad.png");
			sprQuantityPad->setScale(1.0f);
			sprQuantityPad->setPosition(ccp(itemFrame->getContentSize().width, 0));
			sprQuantityPad->setAnchorPoint(ccp(1.0f, 0.0f));
			sprQuantityPad->setTag(TAG_QUANTITY_PAD);
			itemFrame->addChild(sprQuantityPad);

			sprintf(buf, "%d", GDM->equipmentsQuantity[name]);
			CCLabelTTF *labelQuantity = CCLabelTTF::create(buf, "", 12);
			labelQuantity->setPosition(ccp(sprQuantityPad->getContentSize().width / 2, sprQuantityPad->getContentSize().height / 2));
			labelQuantity->setAnchorPoint(ccp(0.5f, 0.5f));
			labelQuantity->setTag(TAG_QUANTITY_LABEL);
			sprQuantityPad->addChild(labelQuantity);

			_arrSprites[i]->push_back(spr);

			x += X_SCALE(ITEM_WIDTH + ITEM_SPACE);
			index++;

			if (index > 0 && (index % COLS_PER_LINE == 0)) {
				x = X_SCALE(ITEM_WIDTH / 2);
				y += Y_SCALE(ITEM_HEIGHT + ITEM_SPACE);
			}
		}

	}

	_layerEquipments[0]->setVisible(true);

	_draggingEquipment = CCSprite::create();
	_draggingEquipment->setScale(0.5f);
	_draggingEquipment->setZOrder(100);
	_layer->addChild(_draggingEquipment);
}

void CollectionScene::createSmeltingPad() {
	CCSize bgSize = CCSizeMake(X_SCALE(410), Y_SCALE(555));

	cocos2d::extension::CCScale9Sprite *sprUnitPadBg = cocos2d::extension::CCScale9Sprite::create("textures/pad_bg.png", CCRectMake(0, 0, 225, 225), CCRectMake(100, 100, 25, 25));
	sprUnitPadBg->setContentSize(bgSize);
	sprUnitPadBg->setPosition(ccp(X_SCALE(525), GM->screenSize.height / 2));
	sprUnitPadBg->setAnchorPoint(ccp(0.0f, 0.5f));
	_layer->addChild(sprUnitPadBg);


}

bool CollectionScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
	if(	_layerEquipmentDetail->isVisible()) {
		_layerEquipmentDetail->setVisible(false);
	}

	auto pt = pTouch->getLocation();
	for (int i = 0; i < (int) EquipmentType::count; i++) {
		if (_tabButtons[i]->hitTest(pt)) {
			_touchPlace = CollectionSceneTouchPlace::tab_button;
			_touchedTabButtonIndex = i;
			break;
		}
	}

	if (_touchPlace == CollectionSceneTouchPlace::blank) {
		if (_layerEquipments[_selectedTabIndex]->hitTest(pt)) {
			_touchPlace = CollectionSceneTouchPlace::equipment_view;

			auto arr = _arrSprites[_selectedTabIndex];
			int index = 0;
			for (auto item : *arr) {
				if (item->hitTest(pt)) {
					_DHLOG("touched item");
					_touchPlace = CollectionSceneTouchPlace::equipment_item;
					_touchedEquipmentIndex = index;
					_draggingStartPos = pt;
					break;
				}
				index++;
			}
		}
	}

	if (_touchPlace == CollectionSceneTouchPlace::blank) {

	}

	return true;
}

void CollectionScene::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
	auto pt = pTouch->getLocation();
	switch (_touchPlace) {
		case CollectionSceneTouchPlace::equipment_view:
			scrollEquipmentView(pTouch->getDelta().y);
	        break;
		case CollectionSceneTouchPlace::equipment_item: {
			float dx = static_cast<float>(fabs(pt.x - _draggingStartPos.x));
			float dy = static_cast<float>(fabs(pt.y - _draggingStartPos.y) * 0.6f);
			_DHLOG("dx: %0.1f, dy: %0.1f", dx, dy);
			if (dx > dy) {
				_touchPlace = CollectionSceneTouchPlace::dragging_equipment;

				string name = GDM->getEquipmentIconFileName((EquipmentType) _selectedTabIndex, _touchedEquipmentIndex);
				_draggingEquipment->setDisplayFrame(MAKE_SPRITEFRAME(name));
				_draggingEquipment->setScale(scales[_selectedTabIndex]);
			} else if (dy > dx) {
				_touchPlace = CollectionSceneTouchPlace::equipment_view;
			}

			break;
		}
		case CollectionSceneTouchPlace::dragging_equipment: {
			CCPoint localPt = _draggingEquipment->getParent()->convertToNodeSpace(pt);
			localPt.x -= X_SCALE(DRAGGING_OFFSET_X);
			localPt.y += Y_SCALE(DRAGGING_OFFSET_Y);
			_draggingEquipment->setVisible(true);
			_draggingEquipment->setPosition(localPt);

			break;
		}
		default:
			break;
	}
}

void CollectionScene::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
	auto pt = pTouch->getLocation();

	switch (_touchPlace) {
		case CollectionSceneTouchPlace::tab_button: {
			if (_tabButtons[_touchedTabButtonIndex]->hitTest(pt)) {
				switchEquipmentView();
			}

			break;
		}
		case CollectionSceneTouchPlace::dragging_equipment:
			pt.x -= X_SCALE(DRAGGING_OFFSET_X);
	        pt.y += Y_SCALE(DRAGGING_OFFSET_Y);
	        handleDroppingEquipment(pt);
	        break;
		case CollectionSceneTouchPlace::equipment_item:
			showEquipmentDetail();
	        break;
		default:
			break;
	}

	_touchedTabButtonIndex = -1;
	_touchedEquipmentIndex = -1;
	_touchPlace = CollectionSceneTouchPlace::blank;
	_draggingEquipment->setVisible(false);
}

void CollectionScene::switchEquipmentView() {
	_tabButtons[_selectedTabIndex]->setDisplayFrame(MAKE_SPRITEFRAME("button/round_button_0.png"));
	_tabButtons[_selectedTabIndex]->setPosition(ccp(10, _tabButtons[_selectedTabIndex]->getPositionY()));
	_layerEquipments[_selectedTabIndex]->setVisible(false);
	_selectedTabIndex = _touchedTabButtonIndex;
	_layerEquipments[_selectedTabIndex]->setVisible(true);

	_tabButtons[_selectedTabIndex]->setDisplayFrame(MAKE_SPRITEFRAME("button/round_button_1.png"));
	_tabButtons[_selectedTabIndex]->setPosition(ccp(0, _tabButtons[_selectedTabIndex]->getPositionY()));
}

void CollectionScene::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {
	_touchedTabButtonIndex = -1;
	_touchedEquipmentIndex = -1;
	_touchPlace = CollectionSceneTouchPlace::blank;
	_draggingEquipment->setVisible(false);
}

void CollectionScene::onClose(CCObject *sender) {
	CCDirector::sharedDirector()->replaceScene(ArmiesScene::create());
}

void CollectionScene::scrollEquipmentView(float distance) {
	CCLayer *layer = _layerEquipments[_selectedTabIndex];

	CCPoint newPt = layer->getPosition();
	newPt.y += distance;

	float miny = layer->getParent()->getContentSize().height - layer->getContentSize().height;
	if (newPt.y < miny) {
		newPt.y = miny;
	}
	if (newPt.y > 0) {
		newPt.y = 0;
	}

	layer->setPosition(newPt);
}

void CollectionScene::handleDroppingEquipment(const CCPoint& pt) {
	CCRect rect = CCRectMake(X_SCALE(560), Y_SCALE(327), X_SCALE(180), Y_SCALE(280));
	if (rect.containsPoint(pt)) {

	}
}

void CollectionScene::keyBackClicked() {
	onClose(nullptr);
}

void CollectionScene::keyMenuClicked() {

}

void CollectionScene::onExit() {
	CCScene::onExit();

	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
	CCDirector::sharedDirector()->getKeypadDispatcher()->removeDelegate(this);
}

void CollectionScene::onEnter() {
	CCScene::onEnter();

	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -1, true);
	CCDirector::sharedDirector()->getKeypadDispatcher()->addDelegate(this);
}

void CollectionScene::showEquipmentDetail() {
	if (_touchedEquipmentIndex >= 0) {
		string name = GDM->getEquipmentName((EquipmentType) _selectedTabIndex, _touchedEquipmentIndex);
		const EquipmentAttribute& attr = GDM->equipmentsAttribute[name];
		_layerEquipmentDetail->setAttribute(name, attr, 0);

		CCSize size = _layerEquipmentDetail->getContentSize();
		CCSprite *sprite = (*(_arrSprites[_selectedTabIndex]))[_touchedEquipmentIndex];
		CCPoint pos = sprite->getParent()->convertToWorldSpace(sprite->getPosition());
		pos.x += ITEM_WIDTH / 2.0f * GM->minscale;
		if (pos.y > GM->screenSize.height - size.height * GM->minscale) {
			pos.y = GM->screenSize.height - size.height * GM->minscale;
		}

		_layerEquipmentDetail->setPosition(pos);
		_layerEquipmentDetail->setVisible(true);
	}
}
